package com.nsn.mib.trap.parser;

import java.io.StringReader;
import java.util.List;

import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.HasWord;
import edu.stanford.nlp.parser.lexparser.LexicalizedParser;
import edu.stanford.nlp.process.CoreLabelTokenFactory;
import edu.stanford.nlp.process.DocumentPreprocessor;
import edu.stanford.nlp.process.PTBTokenizer;
import edu.stanford.nlp.process.TokenizerFactory;
import edu.stanford.nlp.trees.GrammaticalStructure;
import edu.stanford.nlp.trees.GrammaticalStructureFactory;
import edu.stanford.nlp.trees.PennTreebankLanguagePack;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreebankLanguagePack;
import edu.stanford.nlp.trees.TypedDependency;

public class StanfordParser {

	private static StanfordParser instance = null;
	private static LexicalizedParser lp;

	public static StanfordParser getInstance() {
		if (StanfordParser.instance == null) {
			LexicalizedParser lp = LexicalizedParser.loadModel(
					"edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz",
					"-retainTmpSubcategories","-outputFormatOptions",
					//"basicDependencies");
					"treeDependencies");
			StanfordParser.instance = new StanfordParser(lp);
		}
		return StanfordParser.instance;
	}

	public StanfordParser(LexicalizedParser lp) {
		StanfordParser.lp = lp;
	}

	/**
	 * Parse sentences in a file
	 * 
	 * @param SentFilename
	 *            The input file
	 * @return void
	 */
	public void DPFromFile(String SentFilename) {
		TreebankLanguagePack tlp = new PennTreebankLanguagePack();
		GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory();

		for (List<HasWord> sentence : new DocumentPreprocessor(SentFilename)) {
			Tree parse = lp.apply(sentence);
			parse.pennPrint(System.out);
			System.out.println();

			GrammaticalStructure gs = gsf.newGrammaticalStructure(parse);
			List<TypedDependency> tdl = (List<TypedDependency>) gs
					.typedDependenciesCollapsedTree();
					//.typedDependencies();
			System.out.println(tdl);
			System.out.println();
		}
	}

	/**
	 * Parse sentences from a String
	 * 
	 * @param sent
	 *            The input sentence
	 * @return List<TypedDependency> The list for type dependency
	 */
	public List<TypedDependency> DPFromString(String sent) {
		
		Tree parse = TreeFromString(sent);
		TreebankLanguagePack tlp = new PennTreebankLanguagePack();
		GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory();
		GrammaticalStructure gs = gsf.newGrammaticalStructure(parse);
		// Choose the type of dependenciesCollapseTree
		// so that dependencies which do not
		// preserve the tree structure are omitted

		return (List<TypedDependency>) gs.typedDependenciesCollapsedTree();
	}
	
	public List<TypedDependency> BasicDPFromString(String sent)
	{
		Tree parse = TreeFromString(sent);
		TreebankLanguagePack tlp = new PennTreebankLanguagePack();
		GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory();
		GrammaticalStructure gs = gsf.newGrammaticalStructure(parse);
		// Choose the type of dependenciesCollapseTree
		// so that dependencies which do not
		// preserve the tree structure are omitted

		return (List<TypedDependency>) gs.typedDependencies();
	}
	
	public List<CoreLabel> WordsList(String sent)
	{
		TokenizerFactory<CoreLabel> tokenizerFactory = PTBTokenizer.factory(
				new CoreLabelTokenFactory(), "");
		return tokenizerFactory.getTokenizer(
				new StringReader(sent)).tokenize();
	}
	
	public Tree TreeFromString(String sent)
	{
		List<CoreLabel> rawWords = WordsList(sent);
		return lp.apply(rawWords);
	}

}

